【精选】seata + nacos + springboot 配置和使用

您所在的位置:网站首页 seata server 【精选】seata + nacos + springboot 配置和使用

【精选】seata + nacos + springboot 配置和使用

2023-10-19 06:06| 来源: 网络整理| 查看: 265

一.seata 分布式事务 seata是什么? Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。 seata术语 TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,驱动全局事务提交或回滚TM (Transaction Manager) - 事务管理器:定义全局事务的范围:开始全局事务、提交或回滚全局事务。RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。TM 和 RM 是作为 Seata 的客户端与业务系统集成在一起,TC 作为 Seata 的服务端独立部署(即:seata-server) seata AT模式 前提条件 基于支持本地 ACID 事务的关系型数据库Java 应用,通过 JDBC 访问数据库 Seata 中,分布式事务的执行流程: TM 开启分布式事务(TM 向 TC 注册全局事务记录);按业务场景,编排数据库、服务等事务内资源(RM 向 TC 汇报资源准备状态 );TM 结束分布式事务,事务一阶段结束(TM 通知 TC 提交/回滚分布式事务);TC 汇总事务信息,决定分布式事务是提交还是回滚;TC 通知所有 RM 提交/回滚 资源,事务二阶段结束。 原理(TM和RM都会被seate代理数据源): TM执行业务时,会通过aop拦截@GlobalTransactional注解,先查询ThreadLocal是否有XID,如果没有,会请求TC创建一个XID,获取到XID,保存到ThreadLocal;在调用其他服务接口的时候,会把XID存放到Http请求头传给RM;RM从请求头上获取到XID,会保存到Threadlocal,并且向TC注册事务分支(当前微服务的);RM操作sql前,会记录前置镜像到undo_log表,然后执行sql,成功后再记录后置镜像到undo_log表(记录undo_log和执行业务sql是同一事务),然后提交事务;TM调用RM返回,继续执行业务,如果异常,通知TC,然后TC通知所有事务分支进行回滚;RM收到回滚通知,会执行后置镜像sql,将数据还原,然后删除当前XID中undo_log的镜像记录;如果成功,通知TC,然后TC通知所有事务分支;RM收到成功通知,删除当前XID中undo_log的镜像记录; seata AT模式 AT模式一阶段: 在一阶段,Seata 会拦截“业务 SQL”,首先解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,然后执行“业务 SQL”更新业务数据,在业务数据更新之后,再将其保存成“after image”,最后生成行锁。以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性AT模式二阶段: 二阶段如果是提交的话,因为“业务 SQL”在一阶段已经提交至数据库, 所以 Seata 框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可 二阶段如果是回滚的话,Seata 就需要回滚一阶段已经执行的“业务 SQL”,还原业务数据。回滚方式便是用“before image”还原业务数据;但在还原前要首先要校验脏写,对比“数据库当前业务数据”和 “after image”,如果两份数据完全一致就说明没有脏写,可以还原业务数据,如果不一致就说明有脏写,出现脏写就需要转人工处理 二.环境配置 nacos 版本 : nacos-server-2.0.3seata 版本 : seata-server-1.4.0SpringBoot 版本 : 2.4.5SpringCloud 版本 : 2021.1seata-sql文件下载地址 -- the table to store GlobalSession data CREATE TABLE IF NOT EXISTS `global_table` ( `xid` VARCHAR(128) NOT NULL, `transaction_id` BIGINT, `status` TINYINT NOT NULL, `application_id` VARCHAR(32), `transaction_service_group` VARCHAR(32), `transaction_name` VARCHAR(128), `timeout` INT, `begin_time` BIGINT, `application_data` VARCHAR(2000), `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`xid`), KEY `idx_status_gmt_modified` (`status` , `gmt_modified`), KEY `idx_transaction_id` (`transaction_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; -- the table to store BranchSession data CREATE TABLE IF NOT EXISTS `branch_table` ( `branch_id` BIGINT NOT NULL, `xid` VARCHAR(128) NOT NULL, `transaction_id` BIGINT, `resource_group_id` VARCHAR(32), `resource_id` VARCHAR(256), `branch_type` VARCHAR(8), `status` TINYINT, `client_id` VARCHAR(64), `application_data` VARCHAR(2000), `gmt_create` DATETIME(6), `gmt_modified` DATETIME(6), PRIMARY KEY (`branch_id`), KEY `idx_xid` (`xid`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; -- the table to store lock data CREATE TABLE IF NOT EXISTS `lock_table` ( `row_key` VARCHAR(128) NOT NULL, `xid` VARCHAR(128), `transaction_id` BIGINT, `branch_id` BIGINT NOT NULL, `resource_id` VARCHAR(256), `table_name` VARCHAR(32), `pk` VARCHAR(36), `status` TINYINT NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking', `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`row_key`), KEY `idx_status` (`status`), KEY `idx_branch_id` (`branch_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; -- 业务库undo_log表 CREATE TABLE `undo_log` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `branch_id` bigint(20) NOT NULL, `xid` varchar(100) NOT NULL, `context` varchar(128) NOT NULL, `rollback_info` longblob NOT NULL, `log_status` int(11) NOT NULL, `log_created` datetime NOT NULL, `log_modified` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

seata-server 下载 seata-server下载地址 在这里插入图片描述

修改配置文件

解压下载后的seata-server,进入conf目录

修改file.conf 在这里插入图片描述

修改registry.conf 在这里插入图片描述

创建并修改config.text

config.text下载地址

在这里插入图片描述 修改内容如下:

store.mode=db store.db.datasource=druid store.db.dbType=mysql store.db.driverClassName=com.mysql.cj.jdbc.Driver store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true store.db.user=root store.db.password=admin

将修改后的 config.text 放入seata-server的根目录

导入nacos-config.sh

nacos-config.sh下载地址 在这里插入图片描述

将下载后的nacos-config.sh放入seata的conf目录

使用git执行导入命令: sh nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 0af6e97b-a684-4647-b696-7c6d42aecce7 -u nacos -w nacos

命令解析:-h -p 指定nacos的端口地址;-g 指定配置的分组,注意,是配置的分组;-t 指定命名空间id; -u -w指定nacos的用户名和密码,同样,这里开启了nacos注册和配置认证的才需要指定

导入原因:config.txt就是seata各种详细的配置,执行 nacos-config.sh 即可将这些配置导入到nacos,这样就不需要将file.conf和registry.conf放到我们的项目中了,需要什么配置就直接从nacos中读取。注意,config.text有差不多三四条 xxx.xx.xx = (没有值的配置)需要删除,不然上传会报错。 导入成功后,可以在nacos页面看到各种配置(config.text的内容): 在这里插入图片描述 启动nacos 和 seata-server,可以在nacos 服务列表看到seata-server 服务已注册: 在这里插入图片描述

三. 项目配置 导入mven 依赖 io.seata seata-spring-boot-starter 1.4.0 com.alibaba.cloud spring-cloud-starter-alibaba-seata 2021.1 配置项目yml文件 seata: enabled: true enable-auto-data-source-proxy: false application-id: vforumc-user tx-service-group: default_tx_group service: vgroup-mapping: default_tx_group: default disable-global-transaction: false registry: type: nacos nacos: application: seata-server server-addr: 127.0.0.1:8848 namespace: 9811894f-0c22-4fb6-a95d-a39da0f9f71c group: SEATA_GROUP username: nacos password: nacos config: nacos: server-addr: 127.0.0.1:8848 namespace: 9811894f-0c22-4fb6-a95d-a39da0f9f71c group: SEATA_GROUP username: nacos password: nacos 配置数据源代理 @Data @Configuration public class DataSourceConfig { @Value("${spring.datasource.url}") private String url; @Value("${spring.datasource.username}") private String username; @Value("${spring.datasource.password}") private String password; @Value("${spring.datasource.driver-class-name}") private String driveClassName; } package com.hikrobot.vforumcuser.config; import com.zaxxer.hikari.HikariDataSource; import io.seata.rm.datasource.DataSourceProxy; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.annotation.Resource; import javax.sql.DataSource; /** * 数据源代理 */ @Configuration public class DataSourceProxyConfig { @Resource private DataSourceConfig dataSourceConfig; @Bean("dataSource") public DataSource druidDataSource() { HikariDataSource hikariDataSource = new HikariDataSource(); hikariDataSource.setUsername(dataSourceConfig.getUsername()); hikariDataSource.setPassword(dataSourceConfig.getPassword()); hikariDataSource.setJdbcUrl(dataSourceConfig.getUrl()); hikariDataSource.setDriverClassName(dataSourceConfig.getDriveClassName()); return hikariDataSource; } @Bean @Primary public DataSourceProxy dataSourceProxy(DataSource dataSource) { return new DataSourceProxy(dataSource); } } // 配置了代理数据源,启动类排除掉数据源自动配置 @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

依次启动nacos,seata-server,项目,可在seata-server 控制台看到 RM注册成功的日志 在这里插入图片描述

SpringCloud xid无法传递 ,远程服务事务无法回滚 ?

首先确保你引入了spring-cloud-starter-alibaba-seata的依赖.如果xid还无法传递,请确认你是否实现了WebMvcConfigurer,如果是,请参考com.alibaba.cloud.seata.web.SeataHandlerInterceptorConfiguration#addInterceptors的方法.把SeataHandlerInterceptor加入到你的拦截链路中.

开启全局事务

在需要事务管理的方法上添加 @GlobalTransaction 注解 开启全局事务 在这里插入图片描述

观测到 undo_log 日志记录

{"@class":"io.seata.rm.datasource.undo.BranchUndoLog","xid":"10.3.184.240:8091:244194318322958336","branchId":244194396508979200,"sqlUndoLogs":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.undo.SQLUndoLog","sqlType":"UPDATE","tableName":"account","beforeImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords","tableName":"account","rows":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Row","fields":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"id","keyType":"PRIMARY_KEY","type":-5,"value":["java.lang.Long",1]},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"password","keyType":"NULL","type":12,"value":"test01"},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"password_flag","keyType":"NULL","type":-6,"value":1}]]}]]},"afterImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords","tableName":"account","rows":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Row","fields":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"id","keyType":"PRIMARY_KEY","type":-5,"value":["java.lang.Long",1]},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"password","keyType":"NULL","type":12,"value":"test02"},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"password_flag","keyType":"NULL","type":-6,"value":1}]]}]]}}]]} {"@class":"io.seata.rm.datasource.undo.BranchUndoLog","xid":"10.3.184.240:8091:244189118866587648","branchId":244189121894875136,"sqlUndoLogs":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.undo.SQLUndoLog","sqlType":"UPDATE","tableName":"article_statistics","beforeImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords","tableName":"article_statistics","rows":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Row","fields":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"id","keyType":"PRIMARY_KEY","type":-5,"value":["java.lang.Long",1]},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"like_num","keyType":"NULL","type":4,"value":500}]]}]]},"afterImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords","tableName":"article_statistics","rows":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Row","fields":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"id","keyType":"PRIMARY_KEY","type":-5,"value":["java.lang.Long",1]},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"like_num","keyType":"NULL","type":4,"value":700}]]}]]}}]]}

观测到seata-server 回滚记录 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3